import detectEthereumProvider from '@metamask/detect-provider';
import Config, { GoogleCloudProject } from 'config';
import Web3 from 'web3';

export default class Web3Manager {
    static isWalletConnected = async (): Promise<boolean> => {
        const provider = await detectEthereumProvider();
        const eth_accounts = await (window['ethereum'] as any).request({ method: 'eth_accounts' });

        return !!provider && !!eth_accounts && eth_accounts.length;
    };

    static getWalletAddress = async (): Promise<string> => {
        if ((await Web3Manager.isWalletConnected()) == true) {
            const [address] = await (window['ethereum'] as any).request({
                method: 'eth_requestAccounts',
            });
            return address;
        }

        return null;
    };

    static isNetworkMatch = async (network: {}): Promise<boolean> => {
        const chainId = await (window['ethereum'] as any).request({ method: 'eth_chainId' });

        if (network['id'] == 'ronin') {
            return true;
        }

        if (network['id'] == 'bnb_chain') {
            if (
                (chainId == '0x38' && Config.getEnvironment() == GoogleCloudProject.LIVE) ||
                (chainId == '0x38' && Config.getEnvironment() == GoogleCloudProject.INTERNAL)
            ) {
                return true;
            }

            if (chainId == '0x61' && Config.getEnvironment() == GoogleCloudProject.DEV) {
                return true;
            }
        }

        return false;
    };

    static connect = async (): Promise<boolean> => {
        try {
            if (window['ethereum']) {
                const accounts = await (window['ethereum'] as any).request({
                    method: 'wallet_requestPermissions',
                    params: [{ eth_accounts: {} }],
                });

                if (accounts.length > 0) {
                    return true;
                }
            }
        } catch (exception) {
            if (exception.code === 4001) {
                // User rejected request
            }
        }

        return false;
    };

    convertNumberToWei = async (tokenContract: any, amount: number): Promise<string> => {
        const decimals = await tokenContract.methods.decimals().call();
        const web3 = new Web3();

        return web3.utils.toBN('0x' + (amount * 10 ** decimals).toString(16)).toString();
    };

    static fromWei = (amount: number, decimals: number): string => {
        return (amount / 10 ** decimals).toFixed(decimals);
    };
}
